package com.aaa.netty;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import org.springframework.stereotype.Component;

@Component
public class MyWebSocketHanler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    int readIdleTimes=0;
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        NettyConfig.getChannelGroup().add(ctx.channel());
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelInactive");
        System.out.println(ctx.channel()+"断开连接");
        NettyConfig.getChannelGroup().remove(ctx.channel());
        removeUserId(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame s) throws Exception {

        if (s.text().equals("hello")) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ok"));
        } else {
            System.out.println("服务器收到消息" + s.text());
            JSONObject jsonObject = JSONUtil.parseObj(s.text());
            String id = jsonObject.getStr("id");
            NettyConfig.getUserChannelMap().put(id, channelHandlerContext.channel());
            System.out.println(id);
            AttributeKey<Object> key = AttributeKey.valueOf("userId");
            channelHandlerContext.channel().attr(key).setIfAbsent(id);
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("连接服务器成功"));
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent) {
            IdleStateEvent evt1 = (IdleStateEvent) evt;
            String eventType = "";
            switch (evt1.state()) {
                case READER_IDLE:
                    eventType = "读空间";
                    readIdleTimes++;
                    break;
                case WRITER_IDLE:
                    eventType = "写空间";
                    break;
                case ALL_IDLE:
                    eventType = "读写空间";
                    break;
            }
            System.out.println(ctx.channel().remoteAddress() + "超时事件 " + eventType);
        }
        if (readIdleTimes>3){
            System.out.println("超时三次");
            ctx.channel().writeAndFlush("idle close");
            ctx.channel().close();
            NettyConfig.getChannelGroup().remove(ctx.channel());
            removeUserId(ctx);
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        NettyConfig.getChannelGroup().remove(ctx.channel());
        removeUserId(ctx);
        ctx.close();
    }

    private void removeUserId(ChannelHandlerContext ctx){
        AttributeKey<String> key = AttributeKey.valueOf("userId");
        String userId = ctx.channel().attr(key).get();
        NettyConfig.getUserChannelMap().remove(userId);
    }
}
